package com.xiyuan.smartutils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

/**
 * 操作系统命令相关工具类
 *
 * @version v1.0.0 @author lgz 2017-8-27 新建与整理
 */

public final class Runtimes {
    
    private Runtimes() {}
    /***************************************************************/
    // 读取命令操作的结果
    /***************************************************************/
    
    /**
     * 执行命令
     *
     * @param command 无参数命令
     * @throws IOException IO异常要求业务捕捉
     */
    public static Process exec(String command) throws IOException {
        return Runtime.getRuntime().exec(command);
    }
    
    /**
     * 执行命令，
     *
     * @param commands 无参数命令
     * @throws IOException IO异常要求业务捕捉
     */
    public static Process exec(String[] commands) throws IOException {
        return Runtime.getRuntime().exec(commands);
    }
    
    /**
     * 无参数命令获取数据结果字符串
     *
     * @param command  无参数命令
     * @param encoding 编码
     * @return 命令结果
     * @throws IOException IO异常要求业务捕捉
     */
    public static String exec(String command, String encoding) throws IOException {
        return exec(new String[]{command, null, null}, encoding);
    }
    
    /**
     * 无参数命令获取数据结果字符串
     *
     * @param command 命令集
     * @param charset 编码
     * @return 命令结果
     * @throws IOException IO异常要求业务捕捉
     */
    public static String exec(String command, Charset charset) throws IOException {
        return exec(new String[]{command, null, null}, charset);
    }
    
    /**
     * 有参数命令获取数据结果字符串
     *
     * @param cmdarray 命令集
     * @param encoding 编码
     * @return 命令结果
     * @throws IOException IO异常要求业务捕捉
     */
    public static String exec(String[] cmdarray, String encoding) throws IOException {
        return exec(cmdarray, Charset.forName(encoding));
    }
    
    /**
     * 有参数命令获取数据结果字符串
     *
     * @param commands 命令集
     * @param charset  字符集
     * @return 命令结果
     * @throws IOException IO异常要求业务捕捉
     */
    public static String exec(String[] commands, Charset charset) throws IOException {
        return IoUtils.readString(exec(commands).getInputStream(), charset);
    }
    
    /**
     * 有参数命令获取数据结果行，指定需要的行数
     *
     * @param commands   命令行
     * @param encoding   编码
     * @param maxLineNum 行数，则读到指令行数即停止，0表示读所有
     * @return List<String> 字符串列表值
     * @throws IOException IO异常要求业务捕捉
     */
    public static List<String> exec(String[] commands, String encoding, int maxLineNum) throws IOException {
        return exec(commands, Charset.forName(encoding), maxLineNum);
    }
    
    /**
     * 有参数命令获取数据结果行，指定需要的行数
     *
     * @param cmd        命令行
     * @param charset    字符集
     * @param maxLineNum 行数，则读到指令行数即停止，0表示读所有
     * @return List<String> 字符串列表值
     * @throws IOException IO异常要求业务捕捉
     */
    public static List<String> exec(String[] cmd, Charset charset, int maxLineNum) throws IOException {
        List<String> lines = new ArrayList<String>();
        
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(exec(cmd).getInputStream(), charset))) {
            String line = null;
            while ((line = reader.readLine()) != null) {
                lines.add(line);
                
                if (maxLineNum > 0 && lines.size() >= maxLineNum) return lines;
            }
            
            return lines;
        }
    }
    
    /***************************************************************/
    // 双系统通用的功能
    /***************************************************************/
    
    /**
     * 获取第一个MAC地址，结果为null表示未找到
     *
     * @param encoding 编码
     * @return MAC地址
     * @throws IOException IO异常
     */
    public static String getFirstMacAddress(String encoding) throws IOException {
        return Systems.isWindows() ? Windows.getFirstMacAddress(encoding) : Linux.getFirstMacAddress(encoding);
    }
}
